//
//  NSData+VLExtension.m
//  VLink
//
//  Created by michael on 2024/9/2.
//

#import "NSData+VLExtension.h"
#import <CommonCrypto/CommonCryptor.h>

#define INT_DATA_IMP(type) - (type##_t)vl_##type {                 \
type##_t num = 0;                                              \
[self getBytes:&num length:MIN(sizeof(num),self.length)];      \
return num;                                                    \
}                                                              \

#define INT_DATA_IMP1(type) - (type##_t)vl_##type##At:(NSUInteger)idx {      \
type##_t num = 0;                                                       \
[self getBytes:&num range:NSMakeRange(idx, sizeof(num))];               \
return num;                                                             \
}                                                                       \


@implementation NSData (VLExtension)

INT_DATA_IMP(int8)
INT_DATA_IMP(uint8)
INT_DATA_IMP(int16)
INT_DATA_IMP(uint16)
INT_DATA_IMP(int32)
INT_DATA_IMP(uint32)
INT_DATA_IMP(int64)
INT_DATA_IMP(uint64)

INT_DATA_IMP1(int8)
INT_DATA_IMP1(uint8)
INT_DATA_IMP1(int16)
INT_DATA_IMP1(uint16)
INT_DATA_IMP1(int32)
INT_DATA_IMP1(uint32)
INT_DATA_IMP1(int64)
INT_DATA_IMP1(uint64)

- (NSString *)vl_hex {
    NSUInteger length = self.length;
    NSMutableString *result = [NSMutableString stringWithCapacity:length * 2];
    const unsigned char *byte = self.bytes;
    for (int i = 0; i < length; i++, byte++) {
        [result appendFormat:@"%02X", *byte];
    }
    return result;
}

- (NSData *)vl_aes128EncryptWithKey:(NSData *)key {
    NSMutableData *encryptedData = [NSMutableData dataWithLength:self.length + kCCBlockSizeAES128];
    // 设置加密参数
    CCOptions options = kCCOptionECBMode | kCCOptionPKCS7Padding;
    
    // 执行加密
    size_t encryptedLength = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES, options,
                                          key.bytes, key.length,
                                          NULL,
                                          self.bytes, self.length,
                                          encryptedData.mutableBytes, encryptedData.length,
                                          &encryptedLength);
    
    if (cryptStatus == kCCSuccess) {
        encryptedData.length = encryptedLength;
        
        // 转换为十六进制字符串
        NSMutableString *hexString = [NSMutableString stringWithCapacity:(encryptedData.length * 2)];
        const unsigned char *encryptedBytes = encryptedData.bytes;
        for (int i = 0; i < encryptedData.length; i++) {
            [hexString appendFormat:@"%02X", encryptedBytes[i]];
        }
        // 补0至满32位
        while (hexString.length < 32) [hexString appendString:@"0"];
        return hexString.vl_hexData;
    }
    
    return nil;
}

- (NSData *)vl_aes128DecryptWithKey:(NSData *)key {
    NSString *hexString = [self vl_hex];
    NSMutableData *encryptedData = [NSMutableData data];
    for (int i = 0; i < hexString.length; i += 2) {
        NSString *hexByte = [hexString substringWithRange:NSMakeRange(i, 2)];
        NSScanner *scanner = [NSScanner scannerWithString:hexByte];
        unsigned int byteValue = 0;
        [scanner scanHexInt:&byteValue];
        [encryptedData appendBytes:&byteValue length:1];
    }
    
    // 设置解密参数
    CCOptions options = kCCOptionECBMode | kCCOptionPKCS7Padding;
    
    // 执行解密
    NSMutableData *decryptedData = [NSMutableData dataWithLength:encryptedData.length + kCCBlockSizeAES128];
    size_t decryptedLength = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES, options,
                                          key.bytes, key.length,
                                          NULL,
                                          encryptedData.bytes, encryptedData.length,
                                          decryptedData.mutableBytes, decryptedData.length,
                                          &decryptedLength);
    
    if (cryptStatus == kCCSuccess) {
        decryptedData.length = decryptedLength;
        return decryptedData;
    }
    return nil;
}


@end

@implementation NSString (VLExtension)

- (NSData *)vl_hexData {
    NSMutableData *data = [NSMutableData data];
    for (int i = 0; i < self.length; i += 2) {
        NSString *hexStr = [self substringWithRange:NSMakeRange(i, 2)];
        NSScanner *scanner = [NSScanner scannerWithString:hexStr];
        unsigned int intValue;
        [scanner scanHexInt:&intValue];
        [data appendBytes:&intValue length:1];
    }
    return [data copy];
}

@end
